import XEUtils from 'xe-utils'

XEUtils.mixin({
            /**
             * 返回两个时间之间差距,如果结束时间小于开始开始done为fasle
             *
             * @param {Date} startDate 开始日期
             * @param {Date} endDate 结束日期或当期日期
             * @return {Object}
             */
            checkDateDiff(startDate, endDate, ) {
                var startTime, endTime, item, diffTime, rule, len, index
                var result = { done: false, time: 0 }
                startDate = startDate ? XEUtils.toStringDate(startDate) : 0
                endDate = endDate ? XEUtils.toStringDate(endDate) : new Date()
                if (XEUtils.isValidDate(startDate) && XEUtils.isValidDate(endDate)) {
                    startTime = startDate.getTime()
                    endTime = endDate.getTime()
                    diffTime = result.time = endTime - startTime
                    result.done = diffTime > 0 ? true : false;
                }
                return result
            },
            /**
             * 返回html格式的列表，用于打印表格
             *
             * @param {Array} columns 表头字段
             * @param {Array} data 表体数据
             * @param {Array} convert 自定义字典
             * @return {Object}
             */
            jsonToTable(columns, data, convert) {
                let groups = []
                groups = XEUtils.searchTree(columns, (column, index) => column.visible != false, { children: 'children', mapChildren: 'childNodes', original: true })
                    // 获取所有列
                const cols = []
                XEUtils.eachTree(groups, column => {
                        const isColGroup = column.children && column.children.length
                        if (!isColGroup) {
                            cols.push(column)
                        }
                    }, { children: 'childNodes' })
                    // 构建分组层级
                columns = cols
                let colgroups = convertToRows(groups)
                let isPrint = true,
                    isColgroup = true,
                    isHeader = true,
                    original, treeConfig, isMerge;
                const allCls = 'check-all'
                const clss = [
                    'vxe-table',
                    `border--full`,
                    isPrint ? 'is--print' : '',
                    isHeader ? 'show--head' : ''
                ].filter(cls => cls)
                let tables = [
                        `<table class="${clss.join(' ')}" border="0" cellspacing="0" cellpadding="0">`,
                        `<colgroup>${columns.map(column => `<col style="width:${column.width || column.minWidth}px">`).join('')}</colgroup>`
                  ]
                  if (isHeader) {
                  tables.push('<thead>')
                  if (isColgroup && !original) {
                  colgroups.forEach(cols => {
                    tables.push(
                      `<tr>${cols.map(column => {
                        const headAlign = column.headerAlign || column.align// || allHeaderAlign //|| allAlign
                        const classNames =['col--ellipsis',column.class] 
                        const cellTitle = column.name || column.label || ""
                        let Style = getColumnStyle(column)
                        let childWidth = 0
                        let countChild = 0
                        XEUtils.eachTree([column], item => {
                          if (!item.childNodes || !column.childNodes.length) {
                            countChild++
                          }
                          childWidth += item.renderWidth
                        }, { children: 'childNodes' })
                        const cellWidth = childWidth - countChild
                        if (headAlign) {
                          classNames.push(`col--${headAlign}`)
                        }
                        if (column.type === 'checkbox') {
                          return `<th class="${classNames.join(' ')}" colspan="${column._colSpan}" rowspan="${column._rowSpan}"><div ${isPrint ? '' : `style="width: ${cellWidth}px"`}><input type="checkbox" class="${allCls}" ${isAllSelected ? 'checked' : ''}><span>${cellTitle}</span></div></th>`
                        }
                        return `<th class="${classNames.join(' ')}" colspan="${column._colSpan}" rowspan="${column._rowSpan}" title="${cellTitle}"><div ${isPrint ? '' : `style="width: ${cellWidth}px"`}><span>${cellTitle}</span></div></th>`
                      }).join('')}</tr>`
                    )
                  })
                  } else {
                  tables.push(
                    `<tr>${columns.map(column => {
                      const headAlign = column.headerAlign || column.align// || allHeaderAlign //|| allAlign
                      const classNames =['col--ellipsis',column.class] 
                      const cellTitle = column.name || column.label || ""
                      let Style = getColumnStyle(column)
                      if (headAlign) {
                        classNames.push(`col--${headAlign}`)
                      }
                      return `<th class="${classNames.join(' ')}" title="${cellTitle}"><div ${Style ? `style=${Style}` : ``}><span>${cellTitle}</span></div></th>`
                    }).join('')}</tr>`
                  )
                  }
                  tables.push('</thead>')
                  }
                  if (data.length) {
                  tables.push('<tbody>')
                  if (treeConfig) {
                  data.forEach(item => {
                    tables.push(
                      '<tr>' + columns.map(column => {
                        const cellAlign = column.align //|| allAlign/ || allHeaderAlign //|| allAlign
                        const classNames =['col--ellipsis',column.class]
                        const cellTitle = column.name || column.label || ""
                        let cellValue =getCellValue(item,column,convert)
                        let Style = getColumnStyle(column)
                        if (cellAlign) {
                          classNames.push(`col--${cellAlign}`)
                        }
                        if (column.treeNode) {
                          let treeIcon = ''
                          if (item._hasChild) {
                            treeIcon = `<i class="${item._expand ? 'vxe-table--tree-fold-icon' : 'vxe-table--tree-unfold-icon'}"></i>`
                          }
                          classNames.push('vxe-table--tree-node')

                          return `<td class="${classNames.join(' ')}" title="${cellValue}"><div ${Style ? `style=${Style}` : ``}><div class="vxe-table--tree-node-wrapper" style="padding-left: ${item._level * treeOpts.indent}px"><div class="vxe-table--tree-icon-wrapper">${treeIcon}</div><div class="vxe-table--tree-cell">${cellValue}</div></div></div></td>`
                        }
                        return `<td class="${classNames.join(' ')}" title="${cellValue}"><div ${Style ? `style=${Style}` : ``}>${cellValue}</div></td>`
                      }).join('') + '</tr>'
                    )
                  })
                  } else {
                  data.forEach(item => {
                    tables.push(
                      '<tr>' + columns.map(column => {
                        const cellAlign = column.align //|| allAlign// || allHeaderAlign //|| allAlign
                        const classNames =['col--ellipsis',column.class]
                        const cellTitle = column.name || column.label || ""
                        let cellValue =getCellValue(item,column,convert)
                          let Style = getColumnStyle(column)
                        let rowSpan = 1
                        let colSpan = 1
                        if (cellAlign) {
                          classNames.push(`col--${cellAlign}`)
                        }
                        return `<td class="${classNames.join(' ')}" rowspan="${rowSpan}" colspan="${colSpan}" title="${cellValue}"><div ${Style ? `style=${Style}` : ``}>${cellValue}</div></td>`
                      }).join('') + '</tr>'
                    )
                  })
                  }
                  tables.push('</tbody>')
                  }
                  tables.push('</table>')
                  return  tables.join('')
                },
                /**
                 * 复制字符串到粘贴板
                 * @param {String} Str 复制内容
                 */
                stringCopy(Str) {
                    var _input = document.createElement("input"); // 直接构建input
                    _input.value = Str; // 设置内容
                    document.body.appendChild(_input); // 添加临时实例
                    _input.select(); // 选择实例内容
                    try {
                        if (document.execCommand("copy", false, null)) {
                            //success info
                            return true
                        } else {
                            //fail info
                            return false
                        }
                    } catch (err) {
                        //fail info
                        return false
                }
                document.body.removeChild(_input); // 删除临时实例
                },
                rowColorClassName ({row, rowIndex}) {
                    let color = '';
                    switch (row.type) {
                        case 'summary':
                            color = "table-summary";
                            break;
                    }
                    return color;
                },
                /**
                 * 保存文件到本地
                 * @param {*} options 参数
                 */
    _saveLocalFile(options) {
                    console.log('options',options)
                    var filename = options.filename,
                        type = options.type,
                        content = options.content;
                    var name = "".concat(filename, ".").concat(type);

                    if (window.Blob) {
                    var blob = content instanceof Blob ? content : XEUtils.getExportBlobByContent(XEUtils.toString(content), options);

                    if (navigator.msSaveBlob) {
                        navigator.msSaveBlob(blob, name);
                    } else {
                        var linkElem = document.createElement('a');
                        linkElem.target = '_blank';
                        linkElem.download = name;
                        linkElem.href = URL.createObjectURL(blob);
                        document.body.appendChild(linkElem);
                        linkElem.click();
                        document.body.removeChild(linkElem);
                    }

                    return Promise.resolve();
                    }

                    return Promise.reject(new Error('下载失败'));
                },
                getExportBlobByContent(content, options) {
                    if (window.Blob) {
                      return new Blob([content], {
                        type: "text/".concat(options.type)
                      });
                    }
                    return null;
                },
                convertToRows(originColumns){
                    let maxLevel = 1
                    const traverse = (column, parent) => {
                        if (parent) {
                            column._level = parent._level + 1
                            if (maxLevel < column._level) {
                                maxLevel = column._level
                            }
                        }
                        if (column.childNodes && column.childNodes.length) {
                            let colSpan = 0
                            column.childNodes.forEach((subColumn) => {
                                traverse(subColumn, column)
                                colSpan += subColumn._colSpan
                            })
                            column._colSpan = colSpan
                        } else {
                            column._colSpan = 1
                        }
                    }

                    originColumns.forEach((column) => {
                        column._level = 1
                        traverse(column)
                    })

                    const rows = []
                    for (let i = 0; i < maxLevel; i++) {
                        rows.push([])
                    }

                    const allColumns = getConvertColumns(originColumns)

                    allColumns.forEach((column) => {
                        if (column.childNodes && column.childNodes.length) {
                            column._rowSpan = 1
                        } else {
                            column._rowSpan = maxLevel - column._level + 1
                        }
                        rows[column._level - 1].push(column)
                    })
                    return rows
    },
    _getCellValue(item, column, convert){
        column.key = column.key || column.prop
        let cellValue = item[column.key] || typeof item[column.key] === 'number'?item[column.key]: ""
       console.log('item, column, convert',item, column, convert)
        if (typeof column.formatter == "function") {
            cellValue = column.formatter(item)
        } else if (convert && column.key in convert) {
            let key = convert[column.key]
                // 字典转换
            if (Array.isArray(key)) {
                for (let item of key) {
                    if (cellValue == item.value) {
                        cellValue = item.name
                    }
                }
            }
            // 日期转换
            if (key && key.type === 'date' && cellValue) {
                cellValue = XEUtils.toDateString(cellValue, key.format || 'yyyy-MM-dd')
            }
        }
        return cellValue
    },
    /**
     * @param val 输入值
     * @param len 小数位数
     * @param negative 是否负数：true-是（默认）、false-否
     * @returns {*|string}
     * @constructor
     */
    DoubleInput(val, len, negative = true){
        if(!val || !len){
            return val
        }
        let value;
        if (val.length === 1) {
            if (negative) {
                value = val.replace(/[^0-9-]/g, '')
            } else {
                value = val.replace(/[^0-9]/g, '')
            }
        } else {
            let regStr;
            if (negative) {
                // 清除“-”、“数字”和“.”以外的字符
                value = val.replace(/-[^\d.]/g, "");
                // 只保留第一个. 清除多余的
                value = value.replace(/\.{2,}/g, ".");
                value = value.replace(".", "$#$");
                value = value.replace(/\./g, "");
                value = value.replace("$#$", ".");
                regStr = '^-?\\d*(\\.?\\d)';
                if (typeof len === 'number') {
                    regStr = '^-?\\d*(\\.?\\d{0,' + len + '})';
                }
            } else {
                // 清除“数字”和“.”以外的字符
                value = val.replace(/[^\d.]/g, "");
                // 只保留第一个. 清除多余的
                value = value.replace(/\.{2,}/g, ".");
                value = value.replace(".", "$#$");
                value = value.replace(/\./g, "");
                value = value.replace("$#$", ".");
                regStr = '^\\d*(\\.?\\d)';
                if (typeof len === 'number') {
                    regStr = '^\\d*(\\.?\\d{0,' + len + '})';
                }
            }
            let match = value.match(new RegExp(regStr, 'gi'));
            value = (match && match.length > 0 ? match[0] : '') || '';
        }
        return value
    },
    /**
     * @param value 输入值
     * @param negative 是否负数：true-是（默认）、false-否
     * @returns {*}
     * @constructor
     */
    IntInput(value, negative = true){
        if(!value){
            return value
        }
        if (value.length === 1) {
            if (negative) {
                value = value.replace(/[^0-9-]/g, '')
            } else {
                value = value.replace(/[^0-9]/g, '')
            }
        } else {
            if (negative) {
                value = value.replace(/[^\d-]/g, "");
                // 只保留第一个. 清除多余的
                value = value.replace("-", "$#$");
                value = value.replace(/-/g, "");
                value = value.replace("$#$", "-");
            } else {
                value = value.replace(/[^\d]/g, '')
            }
        }
        return value
    },
    procCoveVersion(data,params) {
        let _params = {prefix_field:'code',suffix_field:'version',separator:"-V",}
        params = Object.assign({},_params,params)
        if(XEUtils.isArray(data)){
            data = data.map(item=>XEUtils.procCoveVersion(item,params))
        }
        if(XEUtils.isPlainObject(data)){
            if(data[params.suffix_field]>0) {
                data[params.prefix_field] = data[params.prefix_field] + params.separator + data[params.suffix_field]
            }
        }
        return data;
    }

})
const getSpanOption = (item, column, convert) => {
    column.key = column.key || column.prop
    let option = item.spanOption[column.key];
    let hideField = item.spanOption.hideField;
    if (hideField && hideField.length > 0) {
        if (hideField.indexOf(column.key) !== -1) {
            return {
                rowspan: 0,
                colspan: 0,
            };
        }
    }
    if (option) {
        if (!option.rowspan) {
            option.rowspan = 0;
        }
        if (!option.colspan) {
            option.colspan = 0;
        }
        return option;
    }

    return option
}
const getColumnStyle = (column) => {
    let style = column.style || ""
    if (column.width) {
        style += `width:${column.width}px;`
    }
    if (column.minWidth) {
        style += `min-width:${column.minWidth}px;`
    }
    return style
}
const getCellValue = (item, column, convert) => {
    column.key = column.key || column.prop
    let cellValue = item[column.key] || typeof item[column.key] === 'number'?item[column.key]: ""

    if (typeof column.formatter == "function") {
        cellValue = column.formatter(item)
    } else if (convert && column.key in convert) {
        let key = convert[column.key]
            // 字典转换
        if (Array.isArray(key)) {
            for (let item of key) {
                if (cellValue == item.value) {
                    cellValue = item.name
                }
            }
        }
        // 日期转换
        if (key && key.type === 'date' && cellValue) {
            cellValue = XEUtils.toDateString(cellValue, key.format || 'yyyy-MM-dd')
        }
    }
    return cellValue
}
const convertToRows = (originColumns) => {
    let maxLevel = 1
    const traverse = (column, parent) => {
        if (parent) {
            column._level = parent._level + 1
            if (maxLevel < column._level) {
                maxLevel = column._level
            }
        }
        if (column.childNodes && column.childNodes.length) {
            let colSpan = 0
            column.childNodes.forEach((subColumn) => {
                traverse(subColumn, column)
                colSpan += subColumn._colSpan
            })
            column._colSpan = colSpan
        } else {
            column._colSpan = 1
        }
    }

    originColumns.forEach((column) => {
        column._level = 1
        traverse(column)
    })

    const rows = []
    for (let i = 0; i < maxLevel; i++) {
        rows.push([])
    }

    const allColumns = getConvertColumns(originColumns)

    allColumns.forEach((column) => {
        if (column.childNodes && column.childNodes.length) {
            column._rowSpan = 1
        } else {
            column._rowSpan = maxLevel - column._level + 1
        }
        rows[column._level - 1].push(column)
    })

    return rows
}
const getConvertColumns = (columns) => {
    const result = []
    columns.forEach((column) => {
        if (column.childNodes && column.childNodes.length) {
            result.push(column)
            result.push(...getConvertColumns(column.childNodes))
        } else {
            result.push(column)
        }
    })
    return result
}